Skip to content

fix(cli): five deploy roll-up fixes from the #2957 wave-4 checklist#3169

Merged
bpamiri merged 3 commits into
developfrom
peter/deploy-w4-rollup
Jun 13, 2026
Merged

fix(cli): five deploy roll-up fixes from the #2957 wave-4 checklist#3169
bpamiri merged 3 commits into
developfrom
peter/deploy-w4-rollup

Conversation

@bpamiri

@bpamiri bpamiri commented Jun 12, 2026

Copy link
Copy Markdown
Collaborator

Summary

Wave 4 ("roll-up point fixes") of the #2957 deploy-orchestration campaign — five independent point fixes, each red-first TDD'd against FakeSshPool / dry-run flows.

Ticks these Wave 4 checklist items from #2957's 2026-06-12 re-scope:

Plus one item listed under Wave 2 in the issue but assigned to this wave by the campaign plan:

  • DEP-11c Resolve the real remote home for the proxy config volume (ProxyCommands.cfc:30 hardcodes /home/<user>; root's home is /root).

Changes

Item Fix
DEP-11a AppCommands.remove_conflicting() (docker container ls --all --filter name=^<name>$ --quiet | xargs -r docker container rm --force) dispatched before each app run; AppCommands.stop_old_versions() (label-scoped docker ps excluding the current name, xargs -r docker stop) dispatched best-effort (allowFail=true) after the kamal-proxy cutover so a failed stop of an OLD container can't fail the NEW deploy.
DEP-11b DeploySecretsCli.extract() uses compare(left(line, eq - 1), key) == 0 — exact match like Kamal; previously extract path returned the PATH value.
DEP-11c ProxyCommands.$remoteHome(): /root for the default root ssh user, /home/<user> otherwise; the config volume mount uses it.
$runBash timeout SecretResolver drains stdout via a deadline-bounded available() poll (covers both hang shapes: silent never-exits AND endless streamers), destroyForcibly() on expiry, throws SecretResolver.ResolutionFailed with an actionable message. Default 60s, configurable via init opts.timeoutSeconds. Replaces the unbounded read-to-EOF + waitFor().
rollback --destination rollback() forwards {destination: opts.destination ?: ""} into ConfigLoader.load() — the last verb not applying the overlay (same defect class as the config() fix in #3085).

Testing

Red-first per item, then full CLI suite in the lucee7 docker harness (/wheels/cli/tests?format=json):

  • Red run (before fixes): DeploySecretsCliSpec 1 fail, ProxyCommandsSpec 1 fail, AppCommandsSpec 2 errors, DeployMainCliSpec 3 fail + 1 error, SecretResolverSpec 1 fail.
  • Green run (after): all five bundles 0 fail / 0 error (12, 12, 13, 55, 14 passes respectively).
  • Full CLI suite: 1015 pass / 0 fail / 2 errors — the 2 errors are the known docker-env artifacts (SshClientSpec / SshPoolSpec docker-not-found), matching the campaign baseline tolerance.
  • The timeout spec also asserts the hang is cut at the deadline (< 10s for a sleep 30 secrets command with timeoutSeconds: 1).

Real SSH / remote-docker behavior is unverifiable in this harness — FakeSshPool specs and --dry-run flows are the verification bar here, per campaign convention. The env-gated E2EDeploySpec (DEPLOY_E2E=1) remains the live-SSH follow-up surface.

Refs #2957

🤖 Generated with Claude Code

- DEP-11a: same-version redeploy — force-remove a conflicting same-name
  container before docker run (exact-anchored name filter, xargs -r
  idempotent) and stop superseded versions best-effort after the
  kamal-proxy cutover (AppCommands.remove_conflicting / stop_old_versions,
  wired into DeployMainCli.$deploy).
- DEP-11b: 'wheels deploy secrets extract' key match is now exact —
  CFML == is case-insensitive, so 'extract path' matched the PATH line.
- DEP-11c: kamal-proxy config volume derives the remote home from the
  ssh user (/root for the default root user) instead of hardcoding
  /home/<user>.
- SecretResolver: bounded stdout drain + deadline (default 60s,
  opts.timeoutSeconds) replaces the unbounded waitFor()/read-to-EOF —
  an interactively-blocking secrets command now kills bash and throws
  SecretResolver.ResolutionFailed with a clear message.
- rollback() forwards {destination} into ConfigLoader.load — it was the
  last verb not applying the --destination overlay (same class as 3085).

All five red-first specs plus full CLI suite green in the lucee7 docker
harness (1015 pass / 0 fail; 2 known docker-env artifacts).

Refs #2957

Signed-off-by: Peter Amiri <peter@alurium.com>
@bpamiri bpamiri enabled auto-merge (squash) June 12, 2026 20:20
@github-actions github-actions Bot added the docs label Jun 12, 2026
Peter Amiri added 2 commits June 12, 2026 21:51
Signed-off-by: Peter Amiri <petera@pai.com>
Signed-off-by: Peter Amiri <petera@pai.com>

# Conflicts:
#	cli/lucli/services/deploy/cli/DeployMainCli.cfc
@bpamiri bpamiri merged commit 96bc2ca into develop Jun 13, 2026
8 checks passed
@bpamiri bpamiri deleted the peter/deploy-w4-rollup branch June 13, 2026 05:20
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

deploy: wheels deploy config ignores --destination, so destination overlays can't be inspected

1 participant